﻿using StackExchange.Redis;

namespace ELF.Permissions;

public class PermissionsService : IPermissionsService
{
    private readonly string _remoteServiceBaseUrl = "";
    private readonly IDatabase _redis;
    private readonly HttpClient _httpClient;
    private const string IdentityPermissionsKey = "IDENTITY_PERMISSIONS_KEY_";

    public PermissionsService(HttpClient httpClient, IConnectionMultiplexer connectionMultiplexer)
    {
        this._httpClient = httpClient;
        this._redis = connectionMultiplexer.GetDatabase();
    }

    public async Task<bool> AuthenticateAsync(string userId, string url)
    {
        bool result;
        if (await HasUserPermissionsCacheAsync(userId))
        {
            // 从缓存中获取权限
            result = await _redis.SetContainsAsync($"{IdentityPermissionsKey}{userId}", url);
        }
        else
        {
            // 从远程服务获取权限
            var permissions = await GetUserPermissionsAsync(userId);
            var values = permissions.Select(p => (RedisValue)p).ToArray();
            // 缓存权限
            await _redis.SetAddAsync($"{IdentityPermissionsKey}{userId}", values);
            // 检查是否有权限
            result = permissions.Contains(url);
        }
        return result;
    }

    private async Task<string[]> GetUserPermissionsAsync(string userId)
    {
        var uri = $"{_remoteServiceBaseUrl}Users/Permissions";
        var result = await _httpClient.GetFromJsonAsync<string[]>(uri);
        return result!;
    }

    /// <summary>
    /// 检查用户是否有权限缓存
    /// </summary>
    /// <param name="userId">用户Id</param>
    /// <returns>是否有权限缓存</returns>
    private async Task<bool> HasUserPermissionsCacheAsync(string userId)
    {
        bool result = await _redis.KeyExistsAsync($"{IdentityPermissionsKey}{userId}");
        return result;
    }

}
